package ynu.sxp.demoapp.security;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import org.springframework.web.bind.annotation.*;
import ynu.sxp.demoapp.security.dto.LoginRO;
import ynu.sxp.demoapp.security.dto.RegisterRO;
import ynu.sxp.demoapp.security.dto.TokenVO;
import ynu.sxp.demoapp.security.service.JwkService;
import ynu.sxp.demoapp.security.service.LoginService;
import ynu.sxp.demoapp.security.service.RegisterService;
import ynu.sxp.demoapp.security.service.TokenService;
import ynu.sxp.demoapp.user.entity.UserEntity;

import javax.security.auth.login.LoginException;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;

@RestController
@Tag(name = "Auth", description = "与身份认证相关的接口" )
public class AuthController {

    private final LoginService loginService;
    private final TokenService tokenService;
    private final JwkService jwkService;
    private final RegisterService registerService;

    public AuthController(LoginService loginService, TokenService tokenService, JwkService jwkService, RegisterService registerService) {
        this.loginService = loginService;
        this.tokenService = tokenService;
        this.jwkService = jwkService;
        this.registerService = registerService;
    }

    @GetMapping("/auth/jwk")
    @Operation(summary = "获取公钥", description = "用于获取验证令牌数字签名的公钥")
    public Map<String, Object> GetJwk(){
        return this.jwkService.jwkSet().toJSONObject();
    }

    //修改用户登录方式
    @PostMapping("/auth/login")
    @Operation(summary = "登录", description = "通过用户名和密码登录获取令牌")
    public TokenVO login(@Valid @RequestBody LoginRO ro) throws LoginException {
        var user = loginService.login(ro);
        return tokenService.generateToken(user);
    }

    @PostMapping("/auth/refresh")
    @Operation(summary = "换发新令牌", description = "用刷新令牌换发新的访问令牌")
    public TokenVO refresh(@RequestBody UUID refreshTokenId) {
        return tokenService.refreshToken(refreshTokenId);
    }

    //AuthController增加用户注册
    @PostMapping("/auth/register")
    @Operation(summary = "注册新用户", description = "注册新用户")
    public boolean register(@Valid @RequestBody RegisterRO registerRO) {
        Optional<UserEntity> user = registerService.findByName(registerRO.getUsername());
        if (user.isEmpty()) {
            if (registerService.register(registerRO) != null) {
                return true;
            } else {
                throw new RuntimeException("注册失败！");
            }
        } else {
            throw new RuntimeException("用户名已被使用！");
        }
    }
}
